package com.googlecode.garbagecan.springsecuritystudy.user;

import java.util.SortedSet;
import java.util.TreeSet;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.util.Assert;

public class UserInfo implements UserDetails {

	private static final long serialVersionUID = 1L;
	private String username;
	private String password;
	private String email;
	private boolean enabled;
	private boolean accountNonExpired;
	private boolean accountNonLocked;
	private boolean credentialsNonExpired;
	private GrantedAuthority[] authorities;

	public UserInfo(String username, String password,
			boolean enabled, GrantedAuthority[] authorities)
			throws IllegalArgumentException {
		this(username, password, enabled, true, true, authorities);
	}

	public UserInfo(String username, String password,
			boolean enabled, boolean accountNonExpired,
			boolean credentialsNonExpired, GrantedAuthority[] authorities)
			throws IllegalArgumentException {
		this(username, password, enabled, accountNonExpired, credentialsNonExpired, true, authorities);
	}

	public UserInfo(String username, String password,
			boolean enabled, boolean accountNonExpired,
			boolean credentialsNonExpired, boolean accountNonLocked,
			GrantedAuthority[] authorities) throws IllegalArgumentException {
		if (((username == null) || "".equals(username))
				|| (password == null)) {
			throw new IllegalArgumentException("Cannot pass null or empty values to constructor");
		}

		this.username = username;
		this.password = password;
		this.enabled = enabled;
		this.accountNonExpired = accountNonExpired;
		this.credentialsNonExpired = credentialsNonExpired;
		this.accountNonLocked = accountNonLocked;
		this.authorities = authorities;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public boolean isEnabled() {
		return enabled;
	}

	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public boolean isAccountNonExpired() {
		return accountNonExpired;
	}
	public void setAccountNonExpired(boolean accountNonExpired) {
		this.accountNonExpired = accountNonExpired;
	}

	public boolean isAccountNonLocked() {
		return this.accountNonLocked;
	}
	public void setAccountNonLocked(boolean accountNonLocked) {
		this.accountNonLocked = accountNonLocked;
	}

	public boolean isCredentialsNonExpired() {
		return credentialsNonExpired;
	}
	public void setCredentialsNonExpired(boolean credentialsNonExpired) {
		this.credentialsNonExpired = credentialsNonExpired;
	}

	public GrantedAuthority[] getAuthorities() {
		return authorities;
	}
	protected void setAuthorities(GrantedAuthority[] authorities) {
		Assert.notNull(authorities, "Cannot pass a null GrantedAuthority array");

		// Ensure array iteration order is predictable (as per UserDetails.getAuthorities() contract and SEC-xxx)
		SortedSet sorter = new TreeSet();
		for (int i = 0; i < authorities.length; i++) {
			Assert.notNull(authorities[i], "Granted authority element " + i
					+ " is null - GrantedAuthority[] cannot contain any null elements");
			sorter.add(authorities[i]);
		}
		this.authorities = (GrantedAuthority[]) sorter.toArray(new GrantedAuthority[sorter.size()]);
	}

	@Override
	public String toString() {
		return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
	}

}
